package com.oocl.euc.core.requestform.controller;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.jsonpath.JsonPath;
import com.oocl.euc.common.constant.MailTemplateKey;
import com.oocl.euc.common.constant.ProceduresType;
import com.oocl.euc.common.constant.QATestingResult;
import com.oocl.euc.common.utils.EntityMapToVOUtil;
import com.oocl.euc.core.attachment.model.Attachment;
import com.oocl.euc.core.attachment.repository.AttachmentRepository;
import com.oocl.euc.core.builder.*;
import com.oocl.euc.core.common.ITTestBase;
import com.oocl.euc.core.maintenance.model.EmailTemplate;
import com.oocl.euc.core.maintenance.repository.EmailTemplateRepository;
import com.oocl.euc.core.requestform.model.*;
import com.oocl.euc.core.requestform.repository.*;
import com.oocl.euc.core.requestform.service.EmailSenderService;
import com.oocl.euc.core.requestform.service.RequestFormService;
import com.oocl.euc.core.requestform.vo.RequestFormVO;
import org.junit.After;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import static org.hamcrest.core.Is.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

public class RequestFormControllerIT extends ITTestBase {

    @Autowired
    RequestFormBuilder requestFormBuilder;
    @Autowired
    RequestAttachmentBuilder requestAttachmentBuilder;
    @Autowired
    RequestPostmortemBuilder requestPostmortemBuilder;
    @Autowired
    RequestPostmortemAttachBuilder requestPostmortemAttachBuilder;
    @Autowired
    RequestProceduresBuilder requestProceduresBuilder;
    @Autowired
    AttachmentBuilder attachmentBuilder;
    @Autowired
    EmailTemplateBuilder emailTemplateBuilder;

    @Autowired
    RequestFormRepository requestFormRepository;
    @Autowired
    AttachmentRepository attachmentRepository;
    @Autowired
    RequestAttachmentRepository requestAttachmentRepository;
    @Autowired
    RequestProceduresRepository requestProceduresRepository;
    @Autowired
    RequestPostmortemAttachRepository requestPostmortemAttachRepository;
    @Autowired
    RequestPostmortemRepository requestPostmortemRepository;
    @Autowired
    EmailTemplateRepository emailTemplateRepository;
    @Autowired
    RequestRemarksRepository requestRemarksRepository;
    @Autowired
    RequestRemarksAttachmentRepository requestRemarksAttachmentRepository;

    @Autowired
    RequestFormService requestFormService;
    @Autowired
    EmailSenderService emailSenderService;

    @Autowired
    ObjectMapper objectMapper;

    @After
    public void reset() {

        emailTemplateRepository.deleteAll();
        requestPostmortemAttachRepository.deleteAll();
        requestPostmortemRepository.deleteAll();
        requestProceduresRepository.deleteAll();
        requestRemarksAttachmentRepository.deleteAll();
        requestRemarksRepository.deleteAll();
        requestAttachmentRepository.deleteAll();
        attachmentRepository.deleteAll();
        requestFormRepository.deleteAll();
    }

    @Test
    public void should_return_new_requestform_when_given_a_requestformData() throws Exception {

        Attachment attachment1 = attachmentBuilder.defaultBuilder()
                .withContent("123".getBytes())
                .withContentType("txt")
                .withFileName("testfile.txt")
                .withMd5Code("md5code123456")
                .saveToDB();
        Attachment attachment2 = attachmentBuilder.defaultBuilder()
                .withContent("456".getBytes())
                .withContentType("txt")
                .withFileName("testfile1.txt")
                .withMd5Code("md5code7890")
                .saveToDB();

        RequestAttachment requestAttachment = requestAttachmentBuilder.defaultBuilder()
                .withAttachment(attachment1)
                .create();

        RequestPostmortemAttach requestPostmortemAttach = requestPostmortemAttachBuilder.defaultBuilder()
                .withAttachment(attachment2)
                .create();

        RequestPostmortem requestPostmortem = requestPostmortemBuilder.defaultBuilder()
                .withAttachment(Arrays.asList(requestPostmortemAttach))
                .create();

        RequestProcedures requestProcedures = requestProceduresBuilder.defaultBuilder()
                .withProcedureDesc("Procedures Desc")
                .withProcedureSeq(0)
                .create();

        RequestForm requestForm = requestFormBuilder.defaultBuilder()
                .withRequestAttachments(Arrays.asList(requestAttachment))
                .withRequestPostmortems(Arrays.asList(requestPostmortem))
                .withRequestprocedures(Arrays.asList(requestProcedures))
                .create();

        EmailTemplate emailTemplate = emailTemplateBuilder.defaultBuilder()
                .withKey(MailTemplateKey.ACK_EMAIL)
                .withContent("test")
                .saveToDB();

        RequestFormVO requestFormVO = EntityMapToVOUtil.map(requestForm, RequestFormVO.class);
        requestFormVO.setRequestattachments(requestForm.getRequestattachments());
        requestFormVO.setRequestprocedures(requestForm.getRequestprocedures());
        requestFormVO.setRequestpostmortem(requestForm.getRequestpostmortem());
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        String requestFormJSONStr = objectMapper.writeValueAsString(requestFormVO);

        mockMvc.perform(post("/rest/requestForm/newSubmission")
                .contentType(MediaType.APPLICATION_JSON)
                .content(requestFormJSONStr)
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().contentType("application/json;charset=UTF-8"))
                .andExpect(jsonPath("$.requesterDomainId").value(requestForm.getRequesterDomainId()));
    }

    @Test
    public void should_return_requestForm_when_given_a_refNO() throws Exception {

        RequestForm requestForm = requestFormBuilder.defaultBuilder()
                .withRequestDomainID("LINCO")
                .withRefNO("000001")
                .saveToDB();

        mockMvc.perform(get("/rest/requestForm/findByRefNO/000001").accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().contentType("application/json;charset=UTF-8"))
                .andExpect(jsonPath("$.refNO").value(requestForm.getRefNO()));
    }

    @Test
    public void should_return_requestForm_list_when_given_a_conditionQuery_with_sortOrderList() throws Exception {

        requestFormBuilder.defaultBuilder()
                .withRefNO("000001")
                .saveToDB();
        requestFormBuilder.defaultBuilder()
                .withRefNO("000002")
                .saveToDB();

        String jsonParams = " {\"page\":\"1\",\"start\":\"0\",\"limit\":\"10\",\"sortOrderList\":[{\"direction\":\"DESC\",\"property\":\"id\"}]}";
        mockMvc.perform(post("/rest/requestForm/listQuery")
                .contentType(MediaType.APPLICATION_JSON)
                .content(jsonParams)
                .accept(MediaType.APPLICATION_JSON))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.content.length()",is(2)));

    }

    @Test
    public void should_return_update_requestform_when_given_a_requestformData() throws Exception {

        Attachment attachment1 = attachmentBuilder.defaultBuilder()
                .withContent("123".getBytes())
                .withContentType("txt")
                .withFileName("testfile.txt")
                .withMd5Code("md5code123456")
                .saveToDB();

        RequestPostmortemAttach requestPostmortemAttach = requestPostmortemAttachBuilder.defaultBuilder()
                .withAttachment(attachment1)
                .create();

        RequestPostmortem requestPostmortem = requestPostmortemBuilder.defaultBuilder()
                .withAttachment(Arrays.asList(requestPostmortemAttach))
                .create();

        List<RequestProcedures> requestProceduresList = new ArrayList<>();

        RequestProcedures requestProcedures1 = requestProceduresBuilder.defaultBuilder()
                .withProcedureDesc("Working Procedures Desc")
                .withProcedureSeq(0)
                .withProcedureType(ProceduresType.TYPE_WORKING)
                .create();
        requestProceduresList.add(requestProcedures1);
        RequestProcedures requestProcedures2 = requestProceduresBuilder.defaultBuilder()
                .withProcedureDesc("Verify Procedures Desc")
                .withProcedureSeq(0)
                .withProcedureType(ProceduresType.TYPE_VERIFY)
                .create();
        requestProceduresList.add(requestProcedures2);
        RequestProcedures requestProcedures3 = requestProceduresBuilder.defaultBuilder()
                .withProcedureDesc("Recovery Procedures Desc")
                .withProcedureSeq(0)
                .withProcedureType(ProceduresType.TYPE_RECOVERY)
                .create();
        requestProceduresList.add(requestProcedures3);

        RequestForm requestForm = requestFormBuilder.defaultBuilder()
                .withRequestPostmortems(Arrays.asList(requestPostmortem))
                .withRequestprocedures(requestProceduresList)
                .withRefNO("000001")
                .withCatagoryId("Database")
                .withSubCatagoryId("MySQL")
                .withExpectedDate(new Date())
                .withExpectedTime("12:00")
                .withOnlineServerImpact("test")
                .withOnlineServiceImpactFromDate(new Date())
                .withOnlineServiceImpactToDate(new Date())
                .withPpTrialRunResult(QATestingResult.NO_NEED_TEST)
                .withTestingResult(QATestingResult.NO_NEED_TEST)
                .saveToDB();

        requestForm.setRequesterDomainId("UPDATED");

        RequestFormVO requestFormVO = EntityMapToVOUtil.map(requestForm,RequestFormVO.class);
        requestFormVO.setRequestattachments(requestForm.getRequestattachments());
        requestFormVO.setRequestprocedures(requestForm.getRequestprocedures());
        requestFormVO.setRequestpostmortem(requestForm.getRequestpostmortem());
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        String requestFormJSONStr = objectMapper.writeValueAsString(requestFormVO);

        mockMvc.perform(post("/rest/requestForm/updateRequestForm")
                .contentType(MediaType.APPLICATION_JSON)
                .content(requestFormJSONStr)
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.requesterDomainId",is("UPDATED")));
    }
}